home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / libsrc / c / go32 / dpmi.c next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  10.8 KB  |  414 lines

  1. #include <stdlib.h>
  2. #include <dos.h>
  3. #include <go32.h>
  4. #include <sys/types.h>
  5. #include <dpmi.h>
  6.  
  7. static union REGS r;
  8. static struct SREGS s;
  9.  
  10. int _go32_dpmi_allocate_dos_memory(_go32_dpmi_seginfo *info)
  11. {
  12.   r.x.ax = 0x0100;
  13.   r.x.bx = info->size;
  14.   int86(0x31, &r, &r);
  15.   if (r.x.flags & 1)
  16.   {
  17.     info->size = r.x.bx;
  18.     return r.x.ax;
  19.   }
  20.   else
  21.   {
  22.     info->rm_segment = r.x.ax;
  23.     info->pm_selector = r.x.dx;
  24.     return 0;
  25.   }
  26. }
  27.  
  28. int _go32_dpmi_free_dos_memory(_go32_dpmi_seginfo *info)
  29. {
  30.   r.x.ax = 0x0101;
  31.   r.x.dx = info->pm_selector;
  32.   int86(0x31, &r, &r);
  33.   if (r.x.flags & 1)
  34.   {
  35.     return r.x.ax;
  36.   }
  37.   else
  38.   {
  39.     return 0;
  40.   }
  41. }
  42.  
  43. int _go32_dpmi_resize_dos_memory(_go32_dpmi_seginfo *info)
  44. {
  45.   r.x.ax = 0x0102;
  46.   r.x.bx = info->size;
  47.   r.x.dx = info->pm_selector;
  48.   int86(0x31, &r, &r);
  49.   if (r.x.flags & 1)
  50.   {
  51.     info->size = r.x.bx;
  52.     return r.x.ax;
  53.   }
  54.   else
  55.   {
  56.     return 0;
  57.   }
  58. }
  59.  
  60. int _go32_dpmi_get_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  61. {
  62.   r.x.ax = 0x0200;
  63.   r.h.bl = vector;
  64.   int86(0x31, &r, &r);
  65.   info->rm_segment = r.x.cx;
  66.   info->rm_offset = r.x.dx;
  67.   return 0;
  68. }
  69.  
  70. int _go32_dpmi_set_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  71. {
  72.   r.x.ax = 0x0201;
  73.   r.h.bl = vector;
  74.   r.x.cx = info->rm_segment;
  75.   r.x.dx = info->rm_offset;
  76.   int86(0x31, &r, &r);
  77.   return 0;
  78. }
  79.  
  80. int _go32_dpmi_get_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  81. {
  82.   r.x.ax = 0x0204;
  83.   r.h.bl = vector;
  84.   int86(0x31, &r, &r);
  85.   info->pm_selector = r.x.cx;
  86.   info->pm_offset = r.x.dx;
  87.   return 0;
  88. }
  89.  
  90. int _go32_dpmi_set_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  91. {
  92.   r.x.ax = 0x0205;
  93.   r.h.bl = vector;
  94.   r.x.cx = info->pm_selector;
  95.   r.x.dx = info->pm_offset;
  96.   int86(0x31, &r, &r);
  97.   if (r.x.flags & 1)
  98.   {
  99.     return r.x.ax;
  100.   }
  101.   else
  102.   {
  103.     return 0;
  104.   }
  105. }
  106.  
  107. /* In real DPMI, we enter with only CS known, and SS on a locked 4K stack which
  108.    is *NOT* our SS.  We must set up everthing, including a stack swap, then
  109.    restore it the way we found it.   C. Sandmann 4-93 */
  110.  
  111. static unsigned char wrapper_intcommon[] = {
  112. 0x1e,                        /* push    ds                  */
  113. 0x06,                        /* push    es                  */
  114. 0x0f, 0xa0,                    /* push    fs                  */
  115. 0x0f, 0xa8,                    /* push    gs                  */
  116. 0x60,                        /* pusha                       */
  117. 0x66, 0xb8, 0x34, 0x12,                /* mov     ax,0x1234           */
  118. 0x8e, 0xd8,                    /* mov     ds,ax               */
  119. 0x8e, 0xc0,                    /* mov     es,ax               */
  120. 0x8e, 0xe0,                    /* mov     fs,ax               */
  121. 0x8e, 0xe8,                    /* mov     gs,ax               */
  122. 0xbb, 0x00, 0x00, 0x00, 0x00,            /* mov     ebx,_local_stack    */
  123. 0xfc,                        /* cld                         */
  124. 0x89, 0xe1,                    /* mov     ecx,esp             */
  125. 0x8c, 0xd2,                    /* mov     dx,ss               */
  126. 0x8e, 0xd0,                    /* mov     ss,ax               */
  127. 0x89, 0xdc,                    /* mov     esp,ebx             */
  128. 0x52,                        /* push    edx                 */
  129. 0x51,                        /* push    ecx                 */
  130. 0xe8, 0x00, 0x00, 0x00, 0x00,            /* call    _rmih               */
  131. 0x58,                        /* pop     eax                 */
  132. 0x5b,                        /* pop     ebx                 */
  133. 0x8e, 0xd3,                    /* mov     ss,bx               */
  134. 0x89, 0xc4,                    /* mov     esp,eax             */
  135. 0x61,                        /* popa                        */
  136. 0x0f, 0xa9,                    /* pop     gs                  */
  137. 0x0f, 0xa1,                    /* pop     fs                  */
  138. 0x07,                        /* pop     es                  */
  139. 0x1f                        /* pop     ds                  */
  140. };
  141.  
  142. static unsigned char wrapper_intiret[] = {
  143. 0xcf                        /* iret                        */
  144. };
  145.  
  146. static unsigned char wrapper_intchain[] = {
  147. 0x2e, 0xff, 0x2d, 0x00, 0x00, 0x00, 0x00,    /* jmp     cs:[_old_int+39]    */
  148. 0xcf,                        /* iret                        */
  149. 0x78, 0x56, 0x34, 0x12,
  150. 0xcd, 0xab
  151. };
  152.  
  153. /* _interrupt_stack_size can be changed globally before calling this routine if
  154.    needed.  Don't change it between calls or you will mess up the malloc chain ! */
  155.  
  156. unsigned _interrupt_stack_size = 32256;
  157.  
  158. int _go32_dpmi_chain_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  159. {
  160.   char *mystack;
  161.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intchain));
  162.   if (wrapper == 0)
  163.     return 0x8015;
  164.   mystack = (char *)malloc(_interrupt_stack_size);
  165.   if (mystack == 0)
  166.     return 0x8015;
  167.  
  168.   r.x.ax = 0x0204;
  169.   r.h.bl = vector;
  170.   int86(0x31, &r, &r);
  171.  
  172.   memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
  173.   memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intchain, sizeof(wrapper_intchain));
  174.   *(short *)(wrapper+9) = _go32_my_ds();
  175.   *(long *)(wrapper+20) = (int)mystack + _interrupt_stack_size;
  176.   *(long *)(wrapper+36) = info->pm_offset - (int)wrapper - 40;
  177.   *(long *)(wrapper+sizeof(wrapper_intcommon)+3) = (long)wrapper+sizeof(wrapper_intcommon)+8;
  178.   *(long *)(wrapper+sizeof(wrapper_intcommon)+8) = r.x.dx;
  179.   *(short *)(wrapper+sizeof(wrapper_intcommon)+12) = r.x.cx;
  180.  
  181.   r.x.ax = 0x0205;
  182.   r.h.bl = vector;
  183.   r.x.cx = _go32_my_cs();
  184.   r.x.dx = (int)wrapper;
  185.   int86(0x31, &r, &r);
  186.   return 0;
  187. }
  188.  
  189. int _go32_dpmi_allocate_iret_wrapper(_go32_dpmi_seginfo *info)
  190. {
  191.   char *mystack;
  192.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intiret));
  193.   if (wrapper == 0)
  194.     return 0x8015;
  195.   mystack = (char *)malloc(_interrupt_stack_size);
  196.   if (mystack == 0)
  197.     return 0x8015;
  198.  
  199.   memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
  200.   memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intiret, sizeof(wrapper_intiret));
  201.   *(short *)(wrapper+9) = _go32_my_ds();
  202.   *(long *)(wrapper+20) = (int)mystack + _interrupt_stack_size;
  203.   *(long *)(wrapper+36) = info->pm_offset - (int)wrapper - 40;
  204.  
  205.   info->pm_offset = (int)wrapper;
  206.   return 0;
  207. }
  208.  
  209. int _go32_dpmi_free_iret_wrapper(_go32_dpmi_seginfo *info)
  210. {
  211.   char *mystack;
  212.   char *wrapper = (char *)info->pm_offset;
  213.   mystack = (char *)(*(long *)(wrapper+20) - _interrupt_stack_size);
  214.   free(mystack);
  215.   free(wrapper);
  216.   return 0;
  217. }
  218.  
  219. int _go32_dpmi_simulate_int(int vector, _go32_dpmi_registers *regs)
  220. {
  221.   r.h.bl = vector;
  222.   r.h.bh = 0;
  223.   r.x.cx = 0;
  224.   r.x.di = (int)regs;
  225.   if (vector == 0x21 && regs->x.ax == 0x4b00)
  226.   {
  227.     r.x.ax = 0xff0a;
  228.     int86(0x21, &r, &r);
  229.   }
  230.   else
  231.   {
  232.     r.x.ax = 0x0300;
  233.     int86(0x31, &r, &r);
  234.   }
  235.   if (r.x.flags & 1)
  236.   {
  237.     return r.x.ax;
  238.   }
  239.   else
  240.   {
  241.     return 0;
  242.   }
  243. }
  244.  
  245. int _go32_dpmi_simulate_fcall(_go32_dpmi_registers *regs)
  246. {
  247.   r.x.ax = 0x0301;
  248.   r.h.bh = 0;
  249.   r.x.cx = 0;
  250.   r.x.di = (int)regs;
  251.   int86(0x31, &r, &r);
  252.   if (r.x.flags & 1)
  253.   {
  254.     return r.x.ax;
  255.   }
  256.   else
  257.   {
  258.     return 0;
  259.   }
  260. }
  261.  
  262. int _go32_dpmi_simulate_fcall_iret(_go32_dpmi_registers *regs)
  263. {
  264.   r.x.ax = 0x0302;
  265.   r.h.bh = 0;
  266.   r.x.cx = 0;
  267.   r.x.di = (int)regs;
  268.   int86(0x31, &r, &r);
  269.   if (r.x.flags & 1)
  270.   {
  271.     return r.x.ax;
  272.   }
  273.   else
  274.   {
  275.     return 0;
  276.   }
  277. }
  278.  
  279. /* Bug here; this needs to be fixed like above with SS & CLD */
  280.  
  281. static unsigned char wrapper_common[] = {
  282. 0x66, 0x06,                /* push    es                  */
  283. 0x66, 0x1e,                /* push    ds                  */
  284. 0x66, 0x06,                /* push    es                  */
  285. 0x66, 0x1f,                /* pop     ds                  */
  286. 0x56,                    /* push    esi                 */
  287. 0x57,                    /* push    edi                 */
  288. 0xe8, 0x00, 0x00, 0x00, 0x00,        /* call    _rmcb               */
  289. 0x5f,                    /* pop     edi                 */
  290. 0x5e,                    /* pop     esi                 */
  291. 0x66, 0x1f,                /* pop     ds                  */
  292. 0x66, 0x07,                /* pop     es                  */
  293. 0xfc,                    /* cld                         */
  294. 0x66, 0x8b, 0x06,            /* mov     ax,[esi]            */
  295. 0x66, 0x26, 0x89, 0x47, 0x2a,        /* mov     es:[edi+42],ax      */
  296. 0x66, 0x8b, 0x46, 0x02,            /* mov     ax,[esi+2]          */
  297. 0x66, 0x26, 0x89, 0x47, 0x2c,        /* mov     es:[edi+44],ax      */
  298. };
  299.  
  300. static unsigned char wrapper_retf[] = {
  301. 0x66, 0x26, 0x83, 0x47, 0x2e, 0x04,    /* add     es:[edi+46],0x4     */
  302. 0xcf                    /* iret                        */
  303. };
  304.  
  305. static unsigned char wrapper_iret[] = {
  306. 0x66, 0x8b, 0x46, 0x04,            /* mov     ax,[esi+4]          */
  307. 0x66, 0x26, 0x89, 0x47, 0x20,        /* mov     es:[edi+32],ax      */
  308. 0x66, 0x26, 0x83, 0x47, 0x2e, 0x06,    /* add     es:[edi+46],0x6     */
  309. 0xcf                    /* iret                        */
  310. };
  311.  
  312. int _go32_dpmi_allocate_real_mode_callback_retf(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
  313. {
  314.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_retf));
  315.   if (wrapper == 0)
  316.     return 0x8015;
  317.  
  318.   memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
  319.   memcpy(wrapper+sizeof(wrapper_common), wrapper_retf, sizeof(wrapper_retf));
  320.   *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
  321.   info->size = (int)wrapper;
  322.  
  323.   r.x.ax = 0x0303;
  324.   r.x.si = (int)wrapper;
  325.   r.x.di = (int)regs;
  326.   s.ds = _go32_my_cs();
  327.   s.es = _go32_my_ds();
  328.   s.fs = 0;
  329.   s.gs = 0;
  330.   int86x(0x31, &r, &r, &s);
  331.   if (r.x.flags & 1)
  332.   {
  333.     return r.x.ax;
  334.   }
  335.   else
  336.   {
  337.     info->rm_segment = r.x.cx;
  338.     info->rm_offset = r.x.dx;
  339.     return 0;
  340.   }
  341. }
  342.  
  343. int _go32_dpmi_allocate_real_mode_callback_iret(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
  344. {
  345.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_iret));
  346.   if (wrapper == 0)
  347.     return 0x8015;
  348.  
  349.   memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
  350.   memcpy(wrapper+sizeof(wrapper_common), wrapper_iret, sizeof(wrapper_iret));
  351.   *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
  352.   info->size = (int)wrapper;
  353.  
  354.   r.x.ax = 0x0303;
  355.   r.x.si = (int)wrapper;
  356.   r.x.di = (int)regs;
  357.   s.ds = _go32_my_cs();
  358.   s.es = _go32_my_ds();
  359.   s.fs = 0;
  360.   s.gs = 0;
  361.   int86x(0x31, &r, &r, &s);
  362.   if (r.x.flags & 1)
  363.   {
  364.     return r.x.ax;
  365.   }
  366.   else
  367.   {
  368.     info->rm_segment = r.x.cx;
  369.     info->rm_offset = r.x.dx;
  370.     return 0;
  371.   }
  372. }
  373.  
  374. int _go32_dpmi_free_real_mode_callback(_go32_dpmi_seginfo *info)
  375. {
  376.   free((char *)info->size);
  377.   r.x.ax = 0x0304;
  378.   r.x.cx = info->rm_segment;
  379.   r.x.dx = info->rm_offset;
  380.   int86(0x31, &r, &r);
  381.   if (r.x.flags & 1)
  382.   {
  383.     return r.x.ax;
  384.   }
  385.   else
  386.   {
  387.     return 0;
  388.   }
  389. }
  390.  
  391. int _go32_dpmi_get_free_memory_information(_go32_dpmi_meminfo *info)
  392. {
  393.   r.x.ax = 0x0500;
  394.   r.x.di = (int)info;
  395.   int86(0x31, &r, &r);
  396.   return 0;
  397. }
  398.  
  399. u_long _go32_dpmi_remaining_physical_memory()
  400. {
  401.   _go32_dpmi_meminfo info;
  402.   _go32_dpmi_get_free_memory_information(&info);
  403.   if (info.available_physical_pages)
  404.     return info.available_physical_pages * 4096;
  405.   return info.available_memory;
  406. }
  407.  
  408. u_long _go32_dpmi_remaining_virtual_memory()
  409. {
  410.   _go32_dpmi_meminfo info;
  411.   _go32_dpmi_get_free_memory_information(&info);
  412.   return info.available_memory;
  413. }
  414.